Skip to main content

Explanation

What I-SAW is​

I-SAW ("Infrastructure for Sensing and Analytics on Wildlife") is an edge-networked wildlife observation stack. Its centerpiece is a smart honeypot — an open, see-through bird feeder with no cameras inside it, so birds stay in unobstructed natural context while surrounding sensors do the observing.

Three ideas drive the design:

  • Cross-modal wake-ups ("Bullseye Ambush"). Ultra-low-power audio sentinels listen continuously and wake high-power camera traps over a local MQTT channel only when something is detected. Power, not compute, is the binding constraint in the field.
  • Three-step verification. A visit is confirmed by (1) visual detection from wide-angle AI edge cameras, (2) audio matching of bird song against species call libraries, and (3) footfall sensors on each perch proving a physical landing. Any one channel alone produces false positives; agreement across three modalities does not.
  • Privacy at the edge. Reduction happens on-device, so raw imagery and audio need not leave the deployment site. Only reduced observations travel onward to the hosted cyberinfrastructure.

What this repository is​

This repository is the portal, not the sensing stack. It is a static React single-page app whose job is communication and conversion: explain the project to NSF program managers and K-12 camp counselors, demonstrate the analytics value with a realistic mockup, and hand developers a concrete next step. All sensor data in the sandbox is synthetic and generated in the browser.

Architecture​

index.html
└── src/main.tsx React 19 entry point
└── src/App.tsx Layout, header, footer, tab state
├── components/CanvasBackground.tsx Animated background (global)
├── components/TabVision.tsx Tab 1 — vision & pillars
├── components/TabSandbox.tsx Tab 2 — honeypot, analytics, drone
└── components/TabOnboarding.tsx Tab 3 — quick start, DIY, kit request

Tab state is a single useState in App.tsx; there is no router, no global store, and no data-fetching layer. Each tab owns its own sub-tab state locally. That flatness is intentional — it lets three people edit three files without stepping on each other.

Supporting files:

FileRole
vite.config.tsVite + React + Tailwind v4 plugin, @ path alias, HMR kill-switch
Dockerfile / nginx.confTwo-stage build; nginx serves the SPA
icicle-service.yamlICICLE service identity and runtime declaration
.github/workflows/deploy.yamlDeploys via the shared ICICLE CI/CD template
CLAUDE.mdTeam ownership rules and design conventions

Design choices​

  • Static over dynamic. With no backend, the portal ships as an nginx-served bundle, deploys in seconds, and never exposes a data path that could leak field observations.
  • Tailwind-only visualization. The dashboards, heatmaps, and feeder illustrations are hand-built with Tailwind utilities and inline SVG rather than a charting library. This keeps the bundle small, keeps the visuals on-brand ("nature meets edge AI": deep forest greens, stone/slate darks, glowing emerald accents), and avoids dependency churn in a repo edited by several people at once.
  • Client-side file generation. setup-drone.sh and backpack-config.json are assembled in the browser with a Blob and an object URL, so downloads work with zero server involvement.
  • Motion, used sparingly. motion/react handles tab cross-fades and slide transitions only.
  • A deliberately narrow dependency set. React, Tailwind, lucide-react, and motion. New heavy dependencies require team permission.